package com.zxy.zxyrpc.fault.tolerant;

import com.zxy.zxyrpc.loadBalancer.LoadBalancer;
import com.zxy.zxyrpc.loadBalancer.LoadBalancerFactory;
import com.zxy.zxyrpc.loadBalancer.LoadBalancerKeys;
import com.zxy.zxyrpc.model.RpcRequest;
import com.zxy.zxyrpc.model.RpcResponse;
import com.zxy.zxyrpc.model.ServiceMetaInfo;
import com.zxy.zxyrpc.server.tcp.VertxTcpClient;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * 容错策略 - 故障转移
 *      1.调用另一个节点来处理
 * 实现：for循环，
 *      重新发起调用：每次减少服务节点中的故障节点：可参考：评论去
 *
 * @author zxy
 * @since 2025/5/29
 **/
@Slf4j
public class FailOverTolerantStrategy implements TolerantStrategy {
    @Override
    public RpcResponse doTolerant(Map<String, Object> msg, Exception e) {
        // 采用轮询避免偶发性
        LoadBalancer loadBalancer = LoadBalancerFactory.getInstance(LoadBalancerKeys.ROUND_ROBIN);
        // 请求信息，服务列表，请求响应
        RpcRequest reqMsg = (RpcRequest) msg.get("rpcMsg");
        List<ServiceMetaInfo> serviceList = (List<ServiceMetaInfo>) msg.get("serviceList");
        RpcResponse res = null;
        // 轮询，直到找到一个可用的
        for (ServiceMetaInfo serviceMetaInfo : serviceList) {
            if (res == null){
                try {
                    res = VertxTcpClient.doRequest(reqMsg, serviceMetaInfo);
                } catch (Exception ex) {
                    log.error("故障转移-节点存在故障: " + serviceMetaInfo);
                }
            }

        }
        return res;
    }
}
